package com.yyr.callmessage.core.global;


import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import com.yyr.callmessage.core.config.SystemConfig;
import com.yyr.callmessage.core.constant.SystemError;
import com.yyr.callmessage.core.qo.HttpHeaderQo;
import com.yyr.callmessage.core.ro.BaseRo;
import com.yyr.callmessage.core.util.ServletUtils;
import com.yyr.callmessage.user.domain.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;


@Component
@WebFilter(urlPatterns = "/*")
@Slf4j
public class UserFilter implements Filter {

/*    @Resource
    private AdminService adminService;

    @Resource
    private FactorService factorService;*/

    @Resource
    private UserService userService;

    //unmodifiableSet,返回一个不可修改视图
    private static final Set<String> ExcludePath = Collections.unmodifiableSet(new HashSet<>(
            Arrays.asList("/","/favicon.ico")));

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        //返回请求的URL中调用的servlet的部分，getContextPath是获取项目的根路径，getURI获取根路径到地址结尾
        String path = req.getServletPath();
        if (StringUtils.isBlank(path) || ExcludePath.contains(path)) {
            //执行下一个过滤器或者业务处理器
            chain.doFilter(req, response);
            return;
        }

        //为什么要继承HttpServletRequestWrapper对request中的参数进行过滤或者修改，装饰模式
        RequestWrapper requestWrapper = new RequestWrapper(req);
        //请求类型是options是获取当前URL所支持的方法
        if (!requestWrapper.isOptions()) {
            //前端传过来没值的话设置成Empty，即""
            String platform = Strings.nullToEmpty(req.getHeader("Platform"));
            String token = Strings.nullToEmpty(req.getHeader("Authorization"));
            String version = Strings.nullToEmpty(req.getHeader("Version"));
            String app = Strings.nullToEmpty(req.getHeader("App"));

            Iterable<String> iterable = Splitter.on("/").trimResults().omitEmptyStrings().split(path);
            List<String> paths = Lists.newArrayList(iterable);
            //???
            if (path.length() < 2) {
                chain.doFilter(req, response);
                return;
            }
            // 移除掉版本号
            paths.remove(0);
            // 获取角色权限
            String role = paths.get(0);
            paths.remove(0);
            // 获取接口是否必须登录标志
            // 获取接口是否必须授权标志
            String val = paths.get(0);
            boolean isNeedLogin = false;
            boolean isNeedAuth = false;
            if ("u".equals(val)) {
                isNeedLogin = true;
                paths.remove(0);
                val = paths.get(0);
                if ("p".equals(val)) {
                    isNeedAuth = true;
                    paths.remove(0);
                }
            }

            // 有效的path路径
            String validPath = Joiner.on("/").skipNulls().join(paths);
            // 根据token获取角色信息
            Object userObject = null;
            //登录成功后，需要判断该用户是否有被禁用
            boolean isEnable = false;
            //管理员登录，没被禁用并且需要权限时，需要判断该管理员是否有此权限
            boolean isAuth = false;
            //判断前端传过来的token参数是否有值
            /*if (!Strings.isNullOrEmpty(token)) {
                token = token.replace("Bearer ", "");
                if (role.equals(SystemConfig.RoleAdmin)) {
                    //先查找缓存，再查找数据库，判断是否存在该管理员
                    Admin admin = adminService.getLogin(token);
                    if (admin != null) {
                        //该管理员是否被禁用
                        isEnable = admin.getIsEnable();
                        userObject = admin;

                        //判断是否需要授权，并且是否有权限
                        if (isNeedAuth) {
                            isAuth = adminService.isPermission(admin, validPath, requestWrapper.getMethod());
                        }
                    }

                } else if (role.equals(SystemConfig.RoleUser)) {
                    User user = userService.getLogin(token);
                    if (user != null) {
                        userObject = user;
                        isEnable = user.getIsEnable();
                    }
                }
                else if(role.equals(SystemConfig.RoleFactor)) {
                    // 代理商
                    Factor factor = factorService.getLogin(token);
                    userObject = factor;
                    if (factor != null) {
                        isEnable = factor.getIsEnable();
                    }
                }
            }
*/
           /* //判断是否有登陆并且启用
            if (isNeedLogin && !isEnable) {
                ServletUtils.responseToJson((HttpServletResponse) response, new BaseRo(SystemError.TokenCode, "error.system.token"));
                return;
            }

            //判断是否有权限
            if (isNeedAuth && !isAuth) {
                ServletUtils.responseToJson((HttpServletResponse)response, new BaseRo("error.system.auth"));
                return;
            }*/
            // 封装header
            HttpHeaderQo headerQo = new HttpHeaderQo(platform, version, token, app);
            Gson gson = new GsonBuilder().create();
            String headerJson = gson.toJson(headerQo);
            String userJson = "";
            // 封装用户信息
            if (userObject != null) {
                userJson = gson.toJson(userObject);
            }

            //从请求中接收HttpHeaderQO中的各属性，并且进行通过装饰模式，重新装配
            if (requestWrapper.isGet()) {
                requestWrapper.setAttribute("params", requestWrapper.getParameterMap());
                // get请求放到参数上
                requestWrapper.addParameter("headerJson", headerJson);
                requestWrapper.addParameter("localUserJson", userJson);
            } else {
                requestWrapper.setAttribute("params", requestWrapper.getBodyMap());
                // 其他请求放到body上
                requestWrapper.putBodyParameter("headerJson", headerJson);
                requestWrapper.putBodyParameter("localUserJson", userJson);
            }


        }
        chain.doFilter(requestWrapper, response);
    }


    @Override
    public void destroy() {

    }
}
